package uz.rt.units;

/** Energy class defines an energy with the units: Mev and MV. */
public class Energy
{
// ------------------------------ FIELDS ------------------------------

    /** Magnitude of the energy */
    protected double value;
    /** Energy unit */
    protected Unit unit;

// --------------------------- CONSTRUCTORS ---------------------------

    /**
     * Constructor initialises the class and sets the magnitude and unit of the energy.
     *
     * @param value magnitude of the energy
     * @param unit  energy unit
     */
    public Energy(double value, Unit unit)
    {
        setValue(value);
        setUnit(unit);
    }

    /**
     * Set the magnitude of the energy
     *
     * @param value Magnitude of the energy
     */
    public void setValue(double value)
    {
        if (value >= 0)
            this.value = value;
    }

// --------------------- GETTER / SETTER METHODS ---------------------

    /**
     * Get the energy unit
     *
     * @return Energy unit
     */
    public Unit getUnit()
    {
        return unit;
    }

    /**
     * Set the energy unit
     *
     * @param unit Energy unit
     */
    public void setUnit(Unit unit)
    {
        this.unit = unit;
    }

    /**
     * Get the magnitude of the energy
     *
     * @return Magnitude of the energy
     */
    public double getValue()
    {
        return value;
    }

// ------------------------ CANONICAL METHODS ------------------------

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;
        if (!(o instanceof Energy)) return false;

        Energy energy = (Energy) o;

        return Double.compare(energy.value, value) == 0 && unit == energy.unit;

    }

    @Override
    public int hashCode()
    {
        int result;
        long temp;
        temp = value != +0.0d ? Double.doubleToLongBits(value) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        result = 31 * result + unit.hashCode();
        return result;
    }

    @Override
    public String toString()
    {
        if (unit == Unit.MeV) return String.valueOf(value) + " MeV";
        else if (unit == Unit.MV) return String.valueOf(value) + " MV";
        else return "";
    }

// -------------------------- OTHER METHODS --------------------------

    /**
     * Set the energy unit based on a String value. The current supported energy units in String format are: GMV and
     * MeV.
     *
     * @param unit Energy unit in String format
     */
    public void setUnit(String unit)
    {
        if (unit.equals("MV")) this.unit = Unit.MV;
        else if (unit.equals("MeV")) this.unit = Unit.MeV;
        else throw new RuntimeException(
                    "Trying to set an unknown energy unit. Current supported energy units are: MV and MeV.");
    }

// -------------------------- ENUMERATIONS --------------------------

    /**
     * Energy units:
     * <ul>
     * <li>MV</li>
     * <li>MeV</li>
     * </ul>
     */
    public enum Unit
    {
        MV, MeV
    }
}
